/**
 * iOS 5 style CheckBoxes
 */

;(function(){ 
	var iOSCheckbox = function (elem, options){
		this.elem = $(elem);
		for (var key in options) this[key] = options[key]; 
		
		// init component
		this.elem.wrap('<div class="iToggle"/>');
		this.container = this.elem.parent().append(
			'<label class="iToggleLabelOff"><span>NO</span></label>'+
			'<label class="iToggleLabelOn"><span>YES</span></label>'+
			'<div class="iToggleHandle"></div>'
		);
		this.handle = this.container.find('.iToggleHandle');
		this.offLabel = this.container.find('.iToggleLabelOff');
		this.onLabel = this.container.find('.iToggleLabelOn');
		this.offSpan = this.offLabel.find('span');
		this.onSpan = this.onLabel.find('span');
		if($.browser.msie) $([this.handle, this.offLabel, this.onLabel, this.container]).attr("unselectable", "on");
		
		// init events
		this.elem.on('change', $.proxy(this.onChange, this));
		this.container.on('mousedown touchstart', $.proxy(this.onMouseDown, this));
		$(document)
			.on('mousemove touchmove', $.proxy(this.onGlobalMove, this))
			.on('mouseup touchend', $.proxy(this.onGlobalUp, this));
		
		// init position
		this.offLabel.css({ width: this.container.width() - 10 });
		this.rightSide = this.container.width() - this.handle.width();
		if (this.elem.is(':checked')) {
			this.handle.css({ left: this.rightSide });
			this.onLabel.css({ width: this.rightSide + 10 });
			this.offSpan.css({ marginRight: -this.rightSide });
		} 
		else {
			this.onLabel.css({ width: 10 });
			this.onSpan.css({ marginLeft: -this.rightSide });
		}
		if (this.isDisabled()) this.container.addClass('iToggleDisabled');
	};
	
	iOSCheckbox.prototype.isDisabled = function(){ return this.elem.is(':disabled'); };
	
	iOSCheckbox.prototype.onMouseDown = function(event){
		event.preventDefault();
		if (this.isDisabled()) return;
		var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
		iOSCheckbox.currentlyClicking = this.handle;
		iOSCheckbox.dragStartPosition = x;
		iOSCheckbox.handleLeftOffset = parseInt(this.handle.css('left'), 10) || 0;
	};
	iOSCheckbox.prototype.onDragMove = function(event, x){
		if (iOSCheckbox.currentlyClicking !== this.handle || this.isDisabled()) return;
		var p = (x + iOSCheckbox.handleLeftOffset - iOSCheckbox.dragStartPosition) / this.rightSide;
		if (p < 0) p = 0;
		if (p > 1) p = 1;
		this.handle.css({ left: p * this.rightSide });
		this.onLabel.css({ width: p * this.rightSide + 10 });
		this.offSpan.css({ marginRight: -p * this.rightSide });
		this.onSpan.css({ marginLeft: -(1 - p) * this.rightSide });
	};
	iOSCheckbox.prototype.onDragEnd = function(event, x){
		if (iOSCheckbox.currentlyClicking !== this.handle || this.isDisabled()) return;
		if (iOSCheckbox.dragging) this.elem.prop('checked', (x - iOSCheckbox.dragStartPosition) / this.rightSide >= .5);
		else this.elem.prop('checked', !this.elem.prop('checked'));
		iOSCheckbox.currentlyClicking = null;
		iOSCheckbox.dragging = null;
		this.elem.change();
	};
	iOSCheckbox.prototype.onChange = function(){
		if (this.isDisabled()) { this.container.addClass('iToggleDisabled'); return false; } 
		else this.container.removeClass('iToggleDisabled');
		var new_left = this.elem.prop('checked') ? this.rightSide : 0, animSpeed = 200;
		this.handle.animate({ left: new_left }, animSpeed);
		this.onLabel.animate({ width: new_left + 10 }, animSpeed);
		this.offSpan.animate({ marginRight: -new_left }, animSpeed);
		this.onSpan.animate({ marginLeft: new_left - this.rightSide }, animSpeed);
	};
	iOSCheckbox.prototype.onGlobalMove = function(event){
		if (!iOSCheckbox.currentlyClicking) return;
		event.preventDefault();
		var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
		if (!iOSCheckbox.dragging && (Math.abs(iOSCheckbox.dragStartPosition - x) > 5)) iOSCheckbox.dragging = true;
		this.onDragMove(event, x);
	};
	iOSCheckbox.prototype.onGlobalUp = function(event){
		if (!iOSCheckbox.currentlyClicking) return;
		event.preventDefault();
		var x = event.pageX || event.originalEvent.changedTouches[0].pageX;
		this.onDragEnd(event, x);
    };

	$.fn.iphoneStyle = function(opt){ 
		return this.filter(':checkbox').each(function(){ 
			var chb=$(this); 
			chb.data("iphoneStyle", new iOSCheckbox(chb,opt)); 
		}).end();
	};
})(jQuery);
